#ifndef STX_PLATFORM_POSIX_THREAD_ONCE_HPP
#define STX_PLATFORM_POSIX_THREAD_ONCE_HPP

#include <stx/platform/posix/thread/common.hpp>

namespace stx {

namespace posix {

//  once_control should be defined as follows:
//      static pthread_once_t flag = PTHREAD_ONCE_INIT;
//  The behaviour of pthread_once() is undefined if flag
//  has automatic storage duration or is not initialised by PTHREAD_ONCE_INIT. 

#define STX_POSIX_THREAD_DECLARE_ONCE_FLAG(var_name) \
    pthread_once_t var_name = PTHREAD_ONCE_INIT;

#define STX_POSIX_THREAD_DECLARE_EXTERN_ONCE_FLAG(var_name) \
    extern pthread_once_t var_name;

typedef pthread_once_t once_flag;

inline void call_once(once_flag& flag, void (*init_routine)(void))
{
    int ret = pthread_once(&flag, init_routine);
    if (ret) {
        STX_THROW_SYSTEM_ERROR_VAL(ret, "pthread_once");
    }
}

} // namespace posix

} // namespace stx

#endif // STX_PLATFORM_POSIX_THREAD_ONCE_HPP
